#include <allegro.h>
#include <stdio.h>

#define GFX_W 800
#define GFX_H 600
#define NB_IMAGES 4

struct Mario {
	BITMAP * img_right[NB_IMAGES];
	BITMAP * img_left[NB_IMAGES];
	int x, y;
	int direction; // 0:right 1:left 2:up
};
typedef struct Mario Mario;

int X,Y;

//utils
int get_pixel(BITMAP* Buffer,int x,int y);


//Module Background
BITMAP* load_background_bmp(char chemin_background[]);
void draw_background(BITMAP *Background,BITMAP*Buffer);
void destroy_background(BITMAP * Background);

//Module Mario
void load_mario(Mario *mario);
void destroy_mario(Mario *mario);
void init_mario(Mario *mario);

void move_mario_right(Mario *mario,int *compteur,BITMAP * Background);
void move_mario_left(Mario *mario,int *compteur,BITMAP * Background);
void jump_mario(Mario *mario,BITMAP * Background); //move up
void down_mario(Mario *mario,BITMAP * Background); //move down

void move_mario(Mario *mario,int *compteur,BITMAP * Background);
void draw_mario(Mario mario,BITMAP *Buffer, int compteur);


int main() {

	char chemin_background[]="../images/map_elfe.bmp";
	

	BITMAP *Buffer;
	BITMAP *Background=NULL;
	BITMAP *BackgroundCol=NULL;
	Mario mario;
	
	int compteur;
	
	X=0;
	Y=0;
	/* General initialization function */
	allegro_init();
	if (install_keyboard() == -1) {
		allegro_message("Error! %s", allegro_error);
		return (-1);
	}

	set_color_depth(24);
	if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, GFX_W, GFX_H, 0, 0) != 0) {
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); /* here’s the command for text mode */
		allegro_message("Unable to initialize video mode!\n%s\n", allegro_error);
		return (1);
	}

	Buffer = create_bitmap(SCREEN_W, SCREEN_H);
	//loading images
	//loading mario
	load_mario(&mario);
	//loading background + background collision
	Background=load_background_bmp(chemin_background);
	//loading background collision Map


	//init position & direction
	compteur = 0;
	init_mario(&mario);

	while (!key[KEY_ESC]) {
		//vider le buffer
		clear_bitmap(Buffer);
		//moving mario
		move_mario(&mario,&compteur,BackgroundCol);
		//drawing background
		draw_background(Background,Buffer);
		//drawing mario
		draw_mario(mario,Buffer,compteur);
		//blit Buffer to screen
		blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);

		if (compteur == 10000)
			compteur = 0;
	}
	//destroy Mario
	destroy_mario(&mario);
	destroy_background(Background);
	destroy_bitmap(Buffer);
	return (0);
}
END_OF_MAIN();

/*
 * module background
 */

BITMAP* load_background_bmp(char chemin_background[])
{
	BITMAP* Background;

	Background=load_bitmap(chemin_background, NULL);
	if(Background == NULL){
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to load image !\n%s\n", allegro_error);
		return (NULL);
	}
	return (Background);

}


void draw_background(BITMAP *Background,BITMAP*Buffer)
{
	blit(Background, Buffer, X, Y, 0, 0, SCREEN_W, SCREEN_H);
}

void destroy_background(BITMAP * Background)
{
	destroy_bitmap(Background);
}

/*
 * module mario
 */

void load_mario(Mario *mario)
{
	int i;
	char buf[50];
	for (i = 0; i < NB_IMAGES; i++) {
		sprintf(buf, "../imaages/right%d.bmp", i);
		mario->img_right[i] = load_bitmap(buf, NULL);
		sprintf(buf, "../imaages/left%d.bmp", i);
		mario->img_left[i] = load_bitmap(buf, NULL);
	}
}

void destroy_mario(Mario *mario)
{
	int i;
	for (i = 0; i < NB_IMAGES; i++) {
		destroy_bitmap(mario->img_right[i]);
		destroy_bitmap(mario->img_left[i]);
	}

}
void init_mario(Mario *mario)
{
	mario->direction = 0;
	mario->x = SCREEN_W / 2;
	mario->y = SCREEN_H / 2;
}
void move_mario_right(Mario *mario,int *compteur,BITMAP * Background)
{

	if (key[KEY_RIGHT] && (mario->x < SCREEN_W - mario->img_right[0]->w)) {
		*compteur+=1;

		//(mario->x)+=1;
		X++;
		mario->direction = 0; //right
	}

}

void move_mario_left(Mario *mario,int *compteur,BITMAP * Background)
{

	if (key[KEY_LEFT] && (mario->x > 0 + mario->img_left[0]->w)) {
		*compteur+=1;

		//(mario->x)-=1;
		X--;
		mario->direction = 1; //left
	}
}
void jump_mario(Mario *mario,BITMAP * Background)
{

	if (key[KEY_UP] /*&& (mario->y > 0)*/ ) {
		//(mario->y)-=1;
		Y--;
		mario->direction = 2; //jump
	}

}

void down_mario(Mario *mario,BITMAP * Background)
{

	if (key[KEY_DOWN] /*&& (mario->y > 0)*/ ) {
		//(mario->y)+=1;
		Y++;
		mario->direction = 3; //jump
	}

}

void move_mario(Mario *mario,int *compteur,BITMAP * Background)
{
	move_mario_right(mario,compteur,Background);
	move_mario_left(mario,compteur,Background);
	jump_mario(mario,Background);
	down_mario(mario,Background);
	//add gravity
}
void draw_mario(Mario mario,BITMAP *Buffer, int compteur)
{
	//static int last_direction;

	if (mario.direction == 0){ //moving right

		draw_sprite(Buffer, mario.img_right[compteur % (NB_IMAGES-1) ],mario.x, mario.y);
		//last_direction=0;
	}

	if(mario.direction == 1){ //moving left

		draw_sprite(Buffer, mario.img_left[compteur % (NB_IMAGES-1) ],mario.x, mario.y);
		//last_direction=1;
	}
	if (mario.direction == 2 ) {	//jumping right

		draw_sprite(Buffer, mario.img_right[NB_IMAGES - 1],mario.x, mario.y);
	}
	if (mario.direction == 3 ) {	//jumping left

		draw_sprite(Buffer, mario.img_left[NB_IMAGES - 1],mario.x, mario.y);
	}
}

/*
 * module collision
 */




int get_pixel(BITMAP* Buffer,int x,int y)
{
	int tmp;
	tmp=getpixel(Buffer,x,y);
	return((getr(tmp) + getb(tmp) + getg(tmp)) / 3);
}
